package flat;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;

import utils.Utils;

public class Flat {
	private String file;
	private EPackage model;
	
	public Flat(String in_file, String out_file) {
		file = out_file;
		model = Utils.loadEcore(in_file);
	}
	
	public void save() {
		Utils.saveInstance(file, "ecore", model, EcorePackage.eNS_URI, EcorePackage.eINSTANCE);
	}
	
	public boolean conflicts() {
		List<String> classes = new ArrayList<String>();
		List<String> enums = new ArrayList<String>();
		
		return conflicts(model, classes, enums);
	}
	
	/**
	 * Detecte si le modèle peut être applatit sans conflicts.
	 * @param pack
	 * @param classes
	 * @param enums
	 * @return
	 */
	private boolean conflicts(EPackage pack, List<String> classes, List<String> enums) {
		boolean b = false;
		
		for (EClassifier ec: pack.getEClassifiers()) {
			if (ec instanceof EClass) {
				String name = ((EClass)ec).getName();
				
				if (classes.contains(name)) {
					System.out.println("> conflict ECLass: " + name);
					b = true;
				}
				else {
					classes.add(name);
				}
			}
			else if (ec instanceof EEnum) {
				String name = ((EEnum)ec).getName();
				
				if (enums.contains(name)) {
					System.out.println("> conflict EEnum: " + name);
					b = true;
				}
				else {
					enums.add(name);
				}	
			}
		}
		
		for (EPackage ep: pack.getESubpackages()) {
			b = b || conflicts(ep, classes, enums);
		}
		
		return b;
	}
	
	public void flat() {
		while (model.getESubpackages().size() > 0) {
			EPackage ep = model.getESubpackages().get(0);
			flat(ep);
			model.getESubpackages().remove(ep);
		}
	}
	
	public void flat(EPackage pkg) {
		while (pkg.getEClassifiers().size() > 0) {
			EClassifier ec = pkg.getEClassifiers().get(0);
			System.out.println("> flat: " + ec.getName());
			pkg.getEClassifiers().remove(ec);
			model.getEClassifiers().add(ec);
		}
		
		while (pkg.getESubpackages().size() > 0) {
			EPackage ep = pkg.getESubpackages().get(0);
			flat(ep);
			pkg.getESubpackages().remove(ep);
		}
	}
	
	public static void main(String[] args) {
		Flat flat = new Flat("/udd/deri/ddoose/workspace_pam_v2/pam/model/pam.ecore", "/udd/deri/ddoose/workspace_pam_v2/pam/model/pam_flat");
		
		flat.conflicts();
		flat.flat();
		flat.save();
	}
}
